home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_07_03
/
v7n3083a.txt
< prev
next >
Wrap
Text File
|
1989-03-04
|
16KB
|
626 lines
/* next_string() reads the header file and returns the next NON-COMMENT */
/* string in the file, or NULL if end-of-file is reached */
/* *f is the file pointer for the header file */
char *next_string(f)
FILE *f;
{
int num_fields; /* number of fields read & assigned by fscanf() */
static char instring[256]; /* buffer for fscanf() */
/* WARNING: While INSTRING is declared as a local variable, its */
/* actual scope is more global. INSTRING is declared STATIC */
/* because it is accessed by other functions via the STRING */
/* pointer. The contents of INSTRING must remain valid beyond */
/* the life of the next_string() call. */
char *string; /* pointer to INSTRING */
num_fields=fscanf(f,"%s",instring);
string=instring;
/* throw away the comments */
if(!strncmp("/*", string, 2))
{
do
{
num_fields=fscanf(f,"%s",string);
} while( strncmp("*/",&string[strlen(string)-2],2) && (num_fields != EOF));
/* get the next string after the close of the comment */
/* to return. Make sure that the next string is not also */
/* a comment by using the recursive call */
string=next_string(f);
}
if(num_fields==EOF)
string=NULL;
return(string);
}
Listing 1: The main parsing function of h_filter.
ACUITY_H acuity.h
ACUITY_SCALE_FACTOR acuity.h
CORRECT acuity.h
DATAFILE acuity.h
LARGER acuity.h
NEW_SIZE acuity.h
NO_RESPONSE acuity.h
SEARCH acuity.h
SMALLER acuity.h
STDOUT acuity.h
STDPRN acuity.h
TARG_DOWN acuity.h
TARG_LEFT acuity.h
TARG_RIGHT acuity.h
TARG_UP acuity.h
TRACK acuity.h
VERTICAL_DASH acuity.h
WRONG acuity.h
Table 1: Sample output of h_filter.
AB_END acu_menu.h
ABS itex100.h
ABSOLUTE itex100.h
ACU_MENU_H acu_menu.h
ACUITY_ARRAY_SIZE acu_menu.h
ACUITY_H acuity.h
ACUITY_SCALE_FACTOR acuity.h
AD_IN dt2808.h
ADD itex100.h
ALLOCATION_ERROR itex100.h
ALT keys.h
AND itex100.h
ANSI_H ansi.h
ANY_BUTTON cont_lib.h
aslope scotoma.h
AUTO_PAUSE scotoma.h
Table 2: Fragment of sample output from
h_merge, including the 'a' entries
from table 1.
/* h_filter.c is a utility for extracting names of #define'd constants */
/* and macros, structs, unions, and typedefs from a header file and */
/* creating an alphabetical listing file of the names, like this: */
/* NAME HEADER.H filename, one entry per line in the file. */
/* All header.h filename entries are the same in the output file */
/* The output file can be used to create a cross-reference list of */
/* header file names for a library by combining the appropriate */
/* alphabetical lists using h_merge.c, a companion utility. */
/* */
/* WARNING: h_filter.c uses a simplified version of C grammar, in */
/* which comment delimiters and keywords are assumed to be preceded */
/* and followed by either a space or a newline. Valid C code will not */
/* necessarily be parsed properly. Further, it is assumed that all */
/* struct and union definitions have names, i.e., struct {int a;char b;}c; */
/* will be viewed as having the name "int". */
/* */
/* Written by T. Clune 8/88. Copyright (c) 1988, Eye Research Institute */
/* Boston, MA. Permission is granted to individuals to use this utility */
/* for noncommercial applications. All commercial rights are reserved. */
/* Known MS C-specific aspects of this program are: use of process.h header */
/* file to decalre exit() and use of strcmpi(), which is a Microsoft function */
/* like strcmp() except that the string comparison is case-insensitive. A */
/* usable substitute for strcmpi() is available in my file strcmpi.c. */
#include <stdio.h>
#include <process.h> /* MS C header that declares exit() */
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <search.h>
#define MAXPTRS 500 /* max number of names supported from the .h file */
#define PATH_CHAR '\\' /* path delimiter in MS-DOS */
#define DRIVE_CHAR ':' /* drive designator in MS-DOS */
static char *ptr[MAXPTRS]; /* ptrs to names of definitions in .h file */
static int numptrs; /* the number of names that are actually in the file */
char * next_string();
char * lose_braces();
void extract_names(), put_name();
void make_list();
int compare();
/* main() Usage: h_filter foo.h bar.srt, */
/* where FOO.H is the name of the header file to work on */
/* and BAR.SRT is the alphabetically-sorted list of FOO.H defined names. */
main(argc, argv)
int argc;
char *argv[];
{
FILE *f;
numptrs=0; /* initialize number of names variable */
if(argc != 3)
{
printf("Usage: %s foo.h bar.srt,\n", argv[0]);
printf("\twhere FOO.H is the name of the header file to work on,\n");
printf("\t and BAR.SRT is the alphabetically-sorted list of FOO.H defined names,\n");
exit(-1);
}
if((f=fopen(argv[1], "r"))==NULL)
{
printf("Unable to open %s\n", argv[1]);
exit(-1);
}
extract_names(f);
fclose(f);
make_list(argv[1], argv[2]);
}
/* compare() is the function for qsort() comparisons in make_list() */
int compare(a, b)
char **a, **b;
{
return(strcmpi(*a, *b));
}
/* extract_names() parses the header file, throwing away everything except */
/* #define, struct, union, or typedef names, and sends the names to put_names() */
/* for storage in malloc()ed space. *f is the file pointer for the header file */
void extract_names(f)
FILE *f;
{
char *string, oldstring[256], *str_ptr;
do
{
string=next_string(f);
/* get the names that immediately follow a keyword */
/* (i.e., #define name, struct name, or union name) */
if(!strcmp("#define", string))
{
string=next_string(f);
put_name(string);
}
/* get the '# define' names */
if(!strcmp("#", string))
{
string=next_string(f);
if(!strcmp("define", string))
{
string=next_string(f);
put_name(string);
}
}
/* get struct or union name and throw away the braces */
if( (!strcmp("struct", string)) || (!strcmp("union", string)) )
{
string=next_string(f);
put_name(string);
/* it's either 'struct name{' */
if(str_ptr=strchr(string, '{'))
string=lose_braces(f, str_ptr);
else
{
/* or 'struct name {' */
string=next_string(f);
string=lose_braces(f, string);
}
}
/* for typedefs, the name is the last thing before ';' */
/* i.e., typedef identifier {...} name; */
if(!strcmp("typedef", string))
{
for(;;)
{
string=next_string(f);
if(str_ptr=strchr(string, '{'))
string=lose_braces(f, str_ptr);
/* the end of the typedef condition */
if(str_ptr=strrchr(string,';'))
{
/* this selects between 'name ;' and 'name; ' */
/* if the former,